home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Boxes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  13.0 KB  |  780 lines

  1. /*
  2. **    Boxes.c
  3. **
  4. **    Text box management support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #ifndef _GLOBAL_H
  11. #include "Global.h"
  12. #endif
  13.  
  14.     /* Sizing data. */
  15.  
  16. STATIC struct RastPort    *SZ_RPort;
  17. STATIC struct TextFont    *SZ_TextFont;
  18. STATIC struct Screen    *SZ_Screen;
  19.  
  20. STATIC LONG         SZ_Left,
  21.              SZ_Top,
  22.              SZ_CurrentLeft,
  23.              SZ_CurrentTop,
  24.              SZ_CurrentWidth,
  25.              SZ_MaxWidth,
  26.              SZ_TextPen,
  27.              SZ_BackPen,
  28.              SZ_AverageGlyphWidth;
  29.  
  30.     /* SZ_GetLeftEdge():
  31.      *
  32.      *    Get the current object left edge.
  33.      */
  34.  
  35. LONG
  36. SZ_GetLeftEdge()
  37. {
  38.     return(SZ_CurrentLeft);
  39. }
  40.  
  41.     /* SZ_SetTopEdge(LONG Top):
  42.      *
  43.      *    Set the current object top edge.
  44.      */
  45.  
  46. VOID
  47. SZ_SetTopEdge(LONG Top)
  48. {
  49.     SZ_CurrentTop = Top;
  50. }
  51.  
  52.     /* SZ_SetLeftEdge(LONG Left):
  53.      *
  54.      *    Set the current object left edge.
  55.      */
  56.  
  57. VOID
  58. SZ_SetLeftEdge(LONG Left)
  59. {
  60.     SZ_CurrentLeft = Left;
  61. }
  62.  
  63.     /* SZ_SetAbsoluteTop(LONG Top):
  64.      *
  65.      *    Set new inner window top edge.
  66.      */
  67.  
  68. VOID
  69. SZ_SetAbsoluteTop(LONG Top)
  70. {
  71.     SZ_Top = Top;
  72. }
  73.  
  74.     /* SZ_SetAbsoluteLeft(LONG Left):
  75.      *
  76.      *    Set new inner window left edge.
  77.      */
  78.  
  79. VOID
  80. SZ_SetAbsoluteLeft(LONG Left)
  81. {
  82.     SZ_Left = Left;
  83. }
  84.  
  85.     /* SZ_SetWidth(LONG Width):
  86.      *
  87.      *    Set current object width.
  88.      */
  89.  
  90. VOID
  91. SZ_SetWidth(LONG Width)
  92. {
  93.     SZ_CurrentWidth = Width;
  94. }
  95.  
  96.     /* SZ_AddLeftOffset(LONG Offset):
  97.      *
  98.      *    Update current object left offset.
  99.      */
  100.  
  101. VOID
  102. SZ_AddLeftOffset(LONG Offset)
  103. {
  104.     SZ_CurrentLeft += Offset;
  105. }
  106.  
  107.     /* SZ_LeftOffsetN(LONG DataArray,...):
  108.      *
  109.      *    Determine the maximum length of a number of
  110.      *    gadget labels (first, second, third item, -1 terminates
  111.      *    the array).
  112.      */
  113.  
  114. LONG __stdargs
  115. SZ_LeftOffsetN(LONG DataArray,...)
  116. {
  117.     LONG    *Data = &DataArray,
  118.          Len,
  119.          Max = 0;
  120.     STRPTR     String;
  121.  
  122.     while(*Data != -1)
  123.     {
  124.         String = LocaleString(*Data++);
  125.  
  126.         if((Len = TextLength(SZ_RPort,String,strlen(String))) > Max)
  127.             Max = Len;
  128.     }
  129.  
  130.     return(Max + INTERWIDTH);
  131. }
  132.  
  133.     /* SZ_SizeCleanup():
  134.      *
  135.      *    Free data allocated by SZ_SizeSetup().
  136.      */
  137.  
  138. VOID
  139. SZ_SizeCleanup()
  140. {
  141.     if(SZ_TextFont)
  142.     {
  143.         CloseFont(SZ_TextFont);
  144.  
  145.         SZ_TextFont = NULL;
  146.     }
  147.  
  148.     FreeVecPooled(SZ_RPort);
  149.     SZ_RPort = NULL;
  150. }
  151.  
  152.     /* SZ_SizeSetup(struct Screen *Screen,struct TextAttr *TextAttr):
  153.      *
  154.      *    Perform setups for gadget creation.
  155.      */
  156.  
  157. BOOL
  158. SZ_SizeSetup(struct Screen *Screen,struct TextAttr *TextAttr)
  159. {
  160.     SZ_SizeCleanup();
  161.  
  162.     if(Screen)
  163.     {
  164.         struct DrawInfo *DrawInfo;
  165.  
  166.         if(DrawInfo = GetScreenDrawInfo(Screen))
  167.         {
  168.             SZ_TextPen = DrawInfo -> dri_Pens[TEXTPEN];
  169.             SZ_BackPen = DrawInfo -> dri_Pens[BACKGROUNDPEN];
  170.  
  171.             FreeScreenDrawInfo(Screen,DrawInfo);
  172.         }
  173.     }
  174.     else
  175.     {
  176.         if(!TextAttr)
  177.             return(FALSE);
  178.     }
  179.  
  180.     SZ_Screen = Screen;
  181.  
  182.     if(SZ_RPort = (struct RastPort *)AllocVecPooled(sizeof(struct RastPort),MEMF_ANY | MEMF_CLEAR))
  183.     {
  184.         InitRastPort(SZ_RPort);
  185.  
  186.         if(!TextAttr)
  187.             TextAttr = Screen -> Font;
  188.  
  189.         if(SZ_TextFont = (struct TextFont *)OpenDiskFont(TextAttr))
  190.         {
  191.             LONG    i,Width,Counted = 0,NumericWidth = 0;
  192.             UBYTE    Char;
  193.  
  194.             InterWidth = INTERWIDTH;
  195.  
  196.             if(SZ_TextFont -> tf_YSize <= 8)
  197.                 InterHeight = 1;
  198.             else
  199.                 InterHeight = SZ_TextFont -> tf_YSize / 4;
  200.  
  201.             SetFont(SZ_RPort,SZ_TextFont);
  202.  
  203.             SZ_AverageGlyphWidth = 0;
  204.  
  205.             for(i = 32 ; i < 127 ; i++)
  206.             {
  207.                 Char = i;
  208.  
  209.                 Width = TextLength(SZ_RPort,&Char,1);
  210.  
  211.                     // For really pathologic fonts...
  212.  
  213.                 if(Width < 0 || Width > 32767)
  214.                     continue;
  215.  
  216.                 SZ_AverageGlyphWidth += Width;
  217.  
  218.                 Counted++;
  219.             }
  220.  
  221.             for(i = 160 ; i < 256 ; i++)
  222.             {
  223.                 Char = i;
  224.  
  225.                 Width = TextLength(SZ_RPort,&Char,1);
  226.  
  227.                     // For really pathologic fonts...
  228.  
  229.                 if(Width < 0 || Width > 32767)
  230.                     continue;
  231.  
  232.                 SZ_AverageGlyphWidth += Width;
  233.  
  234.                 Counted++;
  235.             }
  236.  
  237.             for(i = '0' ; i < '9' ; i++)
  238.             {
  239.                 Char = i;
  240.  
  241.                 Width = TextLength(SZ_RPort,&Char,1);
  242.  
  243.                 if(Width > NumericWidth)
  244.                     NumericWidth = Width;
  245.             }
  246.  
  247.             Char = ' ';
  248.  
  249.             Width = TextLength(SZ_RPort,&Char,1);
  250.  
  251.             if(Width > NumericWidth)
  252.                 NumericWidth = Width;
  253.  
  254.             SZ_AverageGlyphWidth /= Counted;
  255.  
  256.             if(SZ_AverageGlyphWidth < NumericWidth)
  257.                 SZ_AverageGlyphWidth = NumericWidth;
  258.  
  259.             SZ_Left = InterWidth;
  260.  
  261.             if(Screen)
  262.                 SZ_Top = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + InterHeight;
  263.             else
  264.                 SZ_Top = 0;
  265.  
  266.             SZ_CurrentLeft    = InterWidth;
  267.             SZ_CurrentTop    = SZ_Top;
  268.  
  269.             SZ_CurrentWidth    = 0;
  270.             SZ_MaxWidth    = 0;
  271.  
  272.             return(TRUE);
  273.         }
  274.     }
  275.  
  276.     SZ_SizeCleanup();
  277.  
  278.     return(FALSE);
  279. }
  280.  
  281.     /* SZ_GetLen(STRPTR String):
  282.      *
  283.      *    Get the string pixel width, measured using the average
  284.      *    glyph width.
  285.      */
  286.  
  287. ULONG
  288. SZ_GetLen(STRPTR String)
  289. {
  290.     return(strlen(String) * SZ_AverageGlyphWidth);
  291. }
  292.  
  293.     /* SZ_FreeBox(struct TextBox *Box):
  294.      *
  295.      *    Free a text box.
  296.      */
  297.  
  298. STATIC VOID
  299. SZ_FreeBox(struct TextBox *Box)
  300. {
  301.     if(Box)
  302.     {
  303.         if(Box -> Text)
  304.         {
  305.             LONG i;
  306.  
  307.             for(i = 0 ; i < Box -> NumLines ; i++)
  308.             {
  309.                 if(Box -> Text[i])
  310.                     FreeVecPooled(Box -> Text[i]);
  311.             }
  312.  
  313.             FreeVecPooled(Box -> Text);
  314.         }
  315.  
  316.         FreeVecPooled(Box -> Title);
  317.  
  318.         FreeVecPooled(Box);
  319.     }
  320. }
  321.  
  322.     /* SZ_FreeBoxes(struct TextBox *FirstBox):
  323.      *
  324.      *    Free a number of text boxes.
  325.      */
  326.  
  327. VOID
  328. SZ_FreeBoxes(struct TextBox *FirstBox)
  329. {
  330.     if(FirstBox)
  331.     {
  332.         struct TextBox *NextBox;
  333.  
  334.         do
  335.         {
  336.             NextBox = FirstBox -> NextBox;
  337.  
  338.             SZ_FreeBox(FirstBox);
  339.  
  340.             FirstBox = NextBox;
  341.         }
  342.         while(FirstBox);
  343.     }
  344. }
  345.  
  346.     /* SZ_BoxWidth(LONG Chars):
  347.      *
  348.      *    Determine the width of a text box.
  349.      */
  350.  
  351. LONG
  352. SZ_BoxWidth(LONG Chars)
  353. {
  354.     return((LONG)(4 + SZ_AverageGlyphWidth * Chars + 4));
  355. }
  356.  
  357.     /* SZ_BoxHeight(LONG Lines):
  358.      *
  359.      *    Determine the height of a text box.
  360.      */
  361.  
  362. LONG
  363. SZ_BoxHeight(LONG Lines)
  364. {
  365.     return(2 + SZ_TextFont -> tf_YSize * Lines + 2);
  366. }
  367.  
  368.     /* SZ_SetTitlePen(struct TextBox *Box,LONG FgPen,LONG BgPen):
  369.      *
  370.      *    Set the text box list title text rendering pens.
  371.      */
  372.  
  373. VOID
  374. SZ_SetTitlePen(struct TextBox *Box,LONG FgPen,LONG BgPen)
  375. {
  376.     while(Box)
  377.     {
  378.         Box -> TitleFgPen = FgPen;
  379.         Box -> TitleBgPen = BgPen;
  380.  
  381.         Box = Box -> NextBox;
  382.     }
  383. }
  384.  
  385.     /* SZ_CreateTextBox(struct TextBox **FirstBox,...):
  386.      *
  387.      *    Create a text box, this routine works similar
  388.      *    to the CreateGadget() frontend.
  389.      */
  390.  
  391. struct TextBox * __stdargs
  392. SZ_CreateTextBox(struct TextBox **FirstBox,...)
  393. {
  394.     va_list         VarArgs;
  395.     struct TagItem    *TagList,
  396.             *ThisTag;
  397.     LONG         Chars,Lines,
  398.              Width,
  399.              Height,
  400.              Left = SZ_CurrentLeft;
  401.     BOOL         AutoWidth    = FALSE,
  402.              MoveDown    = TRUE,
  403.              SetLeft    = FALSE,
  404.              SetBelow    = FALSE;
  405.  
  406.     struct TextBox    *Box;
  407.     LONG         i;
  408.  
  409.     va_start(VarArgs,FirstBox);
  410.  
  411.     TagList = (struct TagItem *)VarArgs;
  412.  
  413.     if(ThisTag = FindTagItem(SZ_Lines,TagList))
  414.         Lines = (LONG)ThisTag -> ti_Data;
  415.     else
  416.         return(NULL);
  417.  
  418.     Height = 2 + SZ_TextFont -> tf_YSize * Lines + 2;
  419.  
  420.     if(ThisTag = FindTagItem(SZ_AutoWidth,TagList))
  421.         AutoWidth = ThisTag -> ti_Data;
  422.  
  423.     if(!AutoWidth)
  424.         return(NULL);
  425.     else
  426.         Chars = (SZ_CurrentWidth - 8) / SZ_AverageGlyphWidth;
  427.  
  428.     if(!(Box = (struct TextBox *)AllocVecPooled(sizeof(struct TextBox),MEMF_ANY | MEMF_CLEAR)))
  429.         return(NULL);
  430.  
  431.     if(ThisTag = FindTagItem(SZ_NewColumn,TagList))
  432.     {
  433.         if(ThisTag -> ti_Data)
  434.         {
  435.             SZ_CurrentTop    = SZ_Top;
  436.             Left        = Left + SZ_MaxWidth + InterWidth;
  437.  
  438.             SZ_MaxWidth    = 0;
  439.         }
  440.     }
  441.  
  442.     if(ThisTag = FindTagItem(SZ_AutoWidth,TagList))
  443.         AutoWidth = ThisTag -> ti_Data;
  444.  
  445.     if(!AutoWidth)
  446.         Width = SZ_BoxWidth(Chars);
  447.     else
  448.         Width = SZ_CurrentWidth;
  449.  
  450.     Box -> Left        = Left;
  451.     Box -> Top        = SZ_CurrentTop;
  452.     Box -> Width        = Width;
  453.     Box -> Height        = Height;
  454.  
  455.     Box -> LineWidth    = Chars * SZ_AverageGlyphWidth;
  456.     Box -> LineHeight    = SZ_TextFont -> tf_YSize;
  457.  
  458.     Box -> NumChars        = Chars;
  459.     Box -> NumLines        = Lines;
  460.  
  461.     Box -> TitleFgPen    = SZ_TextPen;
  462.     Box -> TitleBgPen    = SZ_BackPen;
  463.     Box -> TextPen        = SZ_TextPen;
  464.  
  465.     if(!(Box -> Title = (STRPTR *)AllocVecPooled(sizeof(STRPTR) * Lines,MEMF_ANY | MEMF_CLEAR)))
  466.     {
  467.         SZ_FreeBox(Box);
  468.  
  469.         return(NULL);
  470.     }
  471.  
  472.     if(!(Box -> Text = (STRPTR *)AllocVecPooled(sizeof(STRPTR) * Lines,MEMF_ANY | MEMF_CLEAR)))
  473.     {
  474.         SZ_FreeBox(Box);
  475.  
  476.         return(NULL);
  477.     }
  478.  
  479.     for(i = 0 ; i < Lines ; i++)
  480.     {
  481.         if(!(Box -> Text[i] = (STRPTR)AllocVecPooled(Chars + 1,MEMF_ANY | MEMF_CLEAR)))
  482.         {
  483.             SZ_FreeBox(Box);
  484.  
  485.             return(NULL);
  486.         }
  487.     }
  488.  
  489.     if(SetBelow)
  490.         MoveDown = FALSE;
  491.  
  492.     if(MoveDown)
  493.         SZ_CurrentTop = SZ_CurrentTop + Height + InterHeight;
  494.     else
  495.         SZ_MaxWidth = 0;
  496.  
  497.     if(Width > SZ_MaxWidth)
  498.         SZ_MaxWidth = Width;
  499.  
  500.     if(!SetLeft)
  501.         SZ_CurrentLeft = Left;
  502.  
  503.     if(!(*FirstBox))
  504.         *FirstBox = Box;
  505.     else
  506.     {
  507.         struct TextBox *CurrentBox = *FirstBox;
  508.  
  509.         while(CurrentBox -> NextBox)
  510.             CurrentBox = CurrentBox -> NextBox;
  511.  
  512.         CurrentBox -> NextBox = Box;
  513.     }
  514.  
  515.     return(Box);
  516. }
  517.  
  518.     /* SZ_SetBoxTitles(struct TextBox *Box,STRPTR Array,...):
  519.      *
  520.      *    Set the titles displayed in a text box.
  521.      */
  522.  
  523. VOID __stdargs
  524. SZ_SetBoxTitles(struct TextBox *Box,STRPTR Array,...)
  525. {
  526.     if(Box)
  527.     {
  528.         STRPTR    *Data = &Array;
  529.         LONG     i = 0;
  530.  
  531.         while(*Data != NULL)
  532.         {
  533.             if(i < Box -> NumLines)
  534.                 Box -> Title[i++] = *Data;
  535.  
  536.             Data++;
  537.         }
  538.     }
  539. }
  540.  
  541.     /* SZ_SetLine():
  542.      *
  543.      *    Print a string into a text box, plain version.
  544.      */
  545.  
  546. VOID
  547. SZ_SetLine(struct RastPort *RPort,struct TextBox *Box,LONG Line,STRPTR String)
  548. {
  549.     LONG         FgPen    = ReadAPen(RPort),
  550.              BgPen    = ReadBPen(RPort),
  551.              DrMd    = ReadDrMd(RPort);
  552.     struct TextFont    *Font    = RPort -> Font;
  553.  
  554.     LONG         Width,Len,
  555.              Left    = Box -> Left + 4,
  556.              Top    = Box -> Top + 2 + Line * Box -> LineHeight;
  557.  
  558.     SetPens(RPort,Box -> TextPen,SZ_BackPen,JAM2);
  559.  
  560.     if(Font != UserTextFont)
  561.         SetFont(RPort,UserTextFont);
  562.  
  563.     if(Len = strlen(String))
  564.     {
  565.         if(Len > Box -> NumChars)
  566.             Len = Box -> NumChars;
  567.  
  568.         while(Len > 0 && TextLength(RPort,String,Len) > Box -> LineWidth)
  569.             Len--;
  570.  
  571.         if(Len)
  572.         {
  573.             Width = TextLength(RPort,String,Len);
  574.  
  575.             PlaceText(RPort,Left,Top,String,Len);
  576.         }
  577.         else
  578.             Width = 0;
  579.     }
  580.     else
  581.         Width = 0;
  582.  
  583.     if(Width != Box -> LineWidth)
  584.     {
  585.         if(FgPen != SZ_BackPen)
  586.         {
  587.             SetAPen(RPort,SZ_BackPen);
  588.  
  589.             RectFill(RPort,Left + Width,Top,Left + Box -> LineWidth - 1,Top + Box -> LineHeight - 1);
  590.  
  591.             SetAPen(RPort,FgPen);
  592.         }
  593.         else
  594.             RectFill(RPort,Left + Width,Top,Left + Box -> LineWidth - 1,Top + Box -> LineHeight - 1);
  595.     }
  596.  
  597.     SetPens(RPort,FgPen,BgPen,DrMd);
  598.  
  599.     if(String != Box -> Text[Line])
  600.     {
  601.         if(Len > 0)
  602.             CopyMem(String,Box -> Text[Line],Len);
  603.  
  604.         Box -> Text[Line][Len] = 0;
  605.     }
  606.  
  607.     if(Font != UserTextFont)
  608.         SetFont(RPort,Font);
  609. }
  610.  
  611.     /* SZ_PrintLine():
  612.      *
  613.      *    Print a string into a text box, varargs version.
  614.      */
  615.  
  616. VOID __stdargs
  617. SZ_PrintLine(struct RastPort *RPort,struct TextBox *Box,LONG Line,STRPTR String,...)
  618. {
  619.     va_list    VarArgs;
  620.     UBYTE    Buffer[256];
  621.  
  622.     va_start(VarArgs,String);
  623.     VSPrintf(Buffer,String,VarArgs);
  624.     va_end(VarArgs);
  625.  
  626.     SZ_SetLine(RPort,Box,Line,Buffer);
  627. }
  628.  
  629.     /* SZ_DrawBox(struct RastPort *RPort,struct TextBox *Box):
  630.      *
  631.      *    (Re-)Draw a text box.
  632.      */
  633.  
  634. STATIC VOID
  635. SZ_DrawBox(struct RastPort *RPort,struct TextBox *Box)
  636. {
  637.     if(Box)
  638.     {
  639.         LONG         LineY,i,Len,FgPen = ReadAPen(RPort),BgPen = ReadBPen(RPort),DrMd = ReadDrMd(RPort);
  640.         struct TextFont    *Font = RPort -> Font;
  641.  
  642.         if(Font != UserTextFont)
  643.             SetFont(RPort,UserTextFont);
  644.  
  645.         if(FgPen != SZ_BackPen)
  646.         {
  647.             SetAPen(RPort,SZ_BackPen);
  648.  
  649.             FillBox(RPort,Box -> Left,Box -> Top,Box -> Width,Box -> Height);
  650.  
  651.             SetAPen(RPort,FgPen);
  652.         }
  653.         else
  654.             FillBox(RPort,Box -> Left,Box -> Top,Box -> Width,Box -> Height);
  655.  
  656.         DrawBevelBox(RPort,Box -> Left,Box -> Top,Box -> Width,Box -> Height,
  657.             GT_VisualInfo,    VisualInfo,
  658.             GTBB_Recessed,    TRUE,
  659.         TAG_DONE);
  660.  
  661.         LineY = Box -> Top + 2;
  662.  
  663.         SetPens(RPort,Box -> TitleFgPen,Box -> TitleBgPen,JAM2);
  664.  
  665.         for(i = 0 ; i < Box -> NumLines ; i++)
  666.         {
  667.             if(Len = strlen(Box -> Title[i]))
  668.                 PlaceText(RPort,Box -> Left - INTERWIDTH - TextLength(RPort,Box -> Title[i],Len),LineY,Box -> Title[i],Len);
  669.  
  670.             LineY += Box -> LineHeight;
  671.         }
  672.  
  673.         for(i = 0 ; i < Box -> NumLines ; i++)
  674.             SZ_PrintLine(RPort,Box,i,Box -> Text[i]);
  675.  
  676.         SetPens(RPort,FgPen,BgPen,DrMd);
  677.  
  678.         if(Font != UserTextFont)
  679.             SetFont(RPort,Font);
  680.     }
  681. }
  682.  
  683.     /* SZ_DrawBoxes(struct RastPort *RPort,struct TextBox *FirstBox):
  684.      *
  685.      *    (Re-)Draw a number of text boxes.
  686.      */
  687.  
  688. VOID
  689. SZ_DrawBoxes(struct RastPort *RPort,struct TextBox *FirstBox)
  690. {
  691.     do
  692.         SZ_DrawBox(RPort,FirstBox);
  693.     while(FirstBox = FirstBox -> NextBox);
  694. }
  695.  
  696.     /* SZ_MoveBox(struct TextBox *Box,LONG Left,LONG Top):
  697.      *
  698.      *    Change the location of a text box.
  699.      */
  700.  
  701. STATIC VOID
  702. SZ_MoveBox(struct TextBox *Box,LONG Left,LONG Top)
  703. {
  704.     Box -> Left    += Left;
  705.     Box -> Top    += Top;
  706. }
  707.  
  708.     /* SZ_MoveBoxes(struct TextBox *FirstBox,LONG Left,LONG Top):
  709.      *
  710.      *    Change the locations of a number of text boxes.
  711.      */
  712.  
  713. VOID
  714. SZ_MoveBoxes(struct TextBox *FirstBox,LONG Left,LONG Top)
  715. {
  716.     do
  717.         SZ_MoveBox(FirstBox,Left,Top);
  718.     while(FirstBox = FirstBox -> NextBox);
  719. }
  720.  
  721.     /* SZ_SetBox(struct TextBox *Box,LONG Left,LONG Top):
  722.      *
  723.      *    Set the location of a text box.
  724.      */
  725.  
  726. STATIC VOID
  727. SZ_SetBox(struct TextBox *Box,LONG Left,LONG Top)
  728. {
  729.     if(Left >= 0)
  730.         Box -> Left = Left;
  731.  
  732.     if(Top >= 0)
  733.         Box -> Top = Top;
  734. }
  735.  
  736.     /* SZ_SetBoxes(struct TextBox *FirstBox,LONG Left,LONG Top):
  737.      *
  738.      *    Set the locations of a number of text boxes.
  739.      */
  740.  
  741. VOID
  742. SZ_SetBoxes(struct TextBox *FirstBox,LONG Left,LONG Top)
  743. {
  744.     do
  745.         SZ_SetBox(FirstBox,Left,Top);
  746.     while(FirstBox = FirstBox -> NextBox);
  747. }
  748.  
  749.     /* SZ_GetBoxInfo(struct TextBox *Box,LONG Type):
  750.      *
  751.      *    Query information on a certain text box.
  752.      */
  753.  
  754. LONG
  755. SZ_GetBoxInfo(struct TextBox *Box,LONG Type)
  756. {
  757.     switch(Type)
  758.     {
  759.         case BOX_LEFT:
  760.  
  761.             return(Box -> Left);
  762.  
  763.         case BOX_TOP:
  764.  
  765.             return(Box -> Top);
  766.  
  767.         case BOX_WIDTH:
  768.  
  769.             return(Box -> Width);
  770.  
  771.         case BOX_HEIGHT:
  772.  
  773.             return(Box -> Height);
  774.  
  775.         default:
  776.  
  777.             return(0);
  778.     }
  779. }
  780.